package net.butov.wrappers;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author Maxim Butov
 * @version $Id$
 */
public class AdapterFactory {

    public static final MethodInterceptor ADAPTER_METHOD_INTERCEPTOR = new MethodInterceptor() {
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            if (Modifier.isAbstract(method.getModifiers())) {
                Class type = method.getReturnType();
                if (void.class.equals(type) || !type.isPrimitive()) {
                    return null;
                } else {
                    return Array.get(Array.newInstance(type, 1), 0);
                }
            } else {
                return methodProxy.invokeSuper(obj, args);
            }
        }
    };

    public static <A> EnhancerObjectFactory<A> createFactory(Class<A> abstractClass) {
        return EnhancerObjectFactory.getInstance(abstractClass, ADAPTER_METHOD_INTERCEPTOR);
    }

    public static <A> A createInstance(Class<A> abstractClass) {
        return createFactory(abstractClass).newInstance();
    }

    private AdapterFactory() {
    }
}
